# Some 2020 player statistics
bref_players_stats(seasons = 2020, tables = c("advanced", "totals"), widen = TRUE, assign_to_environment = TRUE)
## Warning: `tbl_df()` is deprecated as of dplyr 1.0.0.
## Please use `tibble::as_tibble()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.
## Warning: `funs()` is deprecated as of dplyr 0.8.0.
## Please use a list of either functions or lambdas: 
## 
##   # Simple named list: 
##   list(mean = mean, median = median)
## 
##   # Auto named with `tibble::lst()`: 
##   tibble::lst(mean, median)
## 
##   # Using lambdas
##   list(~ mean(., trim = .2), ~ median(., na.rm = TRUE))
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.
## Warning: Problem with `mutate()` input `Rk`.
## ℹ NAs introduced by coercion
## ℹ Input `Rk` is `Rk %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `Age`.
## ℹ NAs introduced by coercion
## ℹ Input `Age` is `Age %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `G`.
## ℹ NAs introduced by coercion
## ℹ Input `G` is `G %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `MP`.
## ℹ NAs introduced by coercion
## ℹ Input `MP` is `MP %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `PER`.
## ℹ NAs introduced by coercion
## ℹ Input `PER` is `PER %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `TS.`.
## ℹ NAs introduced by coercion
## ℹ Input `TS.` is `TS. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X3PAr`.
## ℹ NAs introduced by coercion
## ℹ Input `X3PAr` is `X3PAr %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FTr`.
## ℹ NAs introduced by coercion
## ℹ Input `FTr` is `FTr %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `ORB.`.
## ℹ NAs introduced by coercion
## ℹ Input `ORB.` is `ORB. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `DRB.`.
## ℹ NAs introduced by coercion
## ℹ Input `DRB.` is `DRB. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `TRB.`.
## ℹ NAs introduced by coercion
## ℹ Input `TRB.` is `TRB. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `AST.`.
## ℹ NAs introduced by coercion
## ℹ Input `AST.` is `AST. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `STL.`.
## ℹ NAs introduced by coercion
## ℹ Input `STL.` is `STL. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `BLK.`.
## ℹ NAs introduced by coercion
## ℹ Input `BLK.` is `BLK. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `TOV.`.
## ℹ NAs introduced by coercion
## ℹ Input `TOV.` is `TOV. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `USG.`.
## ℹ NAs introduced by coercion
## ℹ Input `USG.` is `USG. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `OWS`.
## ℹ NAs introduced by coercion
## ℹ Input `OWS` is `OWS %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `DWS`.
## ℹ NAs introduced by coercion
## ℹ Input `DWS` is `DWS %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `WS`.
## ℹ NAs introduced by coercion
## ℹ Input `WS` is `WS %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `WS.48`.
## ℹ NAs introduced by coercion
## ℹ Input `WS.48` is `WS.48 %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `OBPM`.
## ℹ NAs introduced by coercion
## ℹ Input `OBPM` is `OBPM %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `DBPM`.
## ℹ NAs introduced by coercion
## ℹ Input `DBPM` is `DBPM %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `BPM`.
## ℹ NAs introduced by coercion
## ℹ Input `BPM` is `BPM %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `VORP`.
## ℹ NAs introduced by coercion
## ℹ Input `VORP` is `VORP %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## parsed http://www.basketball-reference.com/leagues/NBA_2020_advanced.html
## Warning: All elements of `...` must be named.
## Did you want `dataTable = c(isSeasonCurrent, slugPlayerSeason, slugPlayerBREF, namePlayer, 
##     slugPosition, agePlayer, slugTeamBREF, countGames, minutes, 
##     ratioPER, pctTrueShooting, pct3PRate, pctFTRate, pctORB, 
##     pctDRB, pctTRB, pctAST, pctSTL, pctBLK, pctTOV, pctUSG, ratioOWS, 
##     ratioDWS, ratioWS, ratioWSPer48, ratioOBPM, ratioDBPM, ratioBPM, 
##     ratioVORP, isHOFPlayer, slugTeamsBREF, countTeamsPlayerSeason)`?
## Warning: Problem with `mutate()` input `Rk`.
## ℹ NAs introduced by coercion
## ℹ Input `Rk` is `Rk %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `Age`.
## ℹ NAs introduced by coercion
## ℹ Input `Age` is `Age %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `G`.
## ℹ NAs introduced by coercion
## ℹ Input `G` is `G %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `GS`.
## ℹ NAs introduced by coercion
## ℹ Input `GS` is `GS %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `MP`.
## ℹ NAs introduced by coercion
## ℹ Input `MP` is `MP %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FG`.
## ℹ NAs introduced by coercion
## ℹ Input `FG` is `FG %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FGA`.
## ℹ NAs introduced by coercion
## ℹ Input `FGA` is `FGA %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FG.`.
## ℹ NAs introduced by coercion
## ℹ Input `FG.` is `FG. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X3P`.
## ℹ NAs introduced by coercion
## ℹ Input `X3P` is `X3P %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X3PA`.
## ℹ NAs introduced by coercion
## ℹ Input `X3PA` is `X3PA %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X3P.`.
## ℹ NAs introduced by coercion
## ℹ Input `X3P.` is `X3P. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X2P`.
## ℹ NAs introduced by coercion
## ℹ Input `X2P` is `X2P %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X2PA`.
## ℹ NAs introduced by coercion
## ℹ Input `X2PA` is `X2PA %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X2P.`.
## ℹ NAs introduced by coercion
## ℹ Input `X2P.` is `X2P. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `eFG.`.
## ℹ NAs introduced by coercion
## ℹ Input `eFG.` is `eFG. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FT`.
## ℹ NAs introduced by coercion
## ℹ Input `FT` is `FT %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FTA`.
## ℹ NAs introduced by coercion
## ℹ Input `FTA` is `FTA %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FT.`.
## ℹ NAs introduced by coercion
## ℹ Input `FT.` is `FT. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `ORB`.
## ℹ NAs introduced by coercion
## ℹ Input `ORB` is `ORB %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `DRB`.
## ℹ NAs introduced by coercion
## ℹ Input `DRB` is `DRB %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `TRB`.
## ℹ NAs introduced by coercion
## ℹ Input `TRB` is `TRB %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `AST`.
## ℹ NAs introduced by coercion
## ℹ Input `AST` is `AST %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `STL`.
## ℹ NAs introduced by coercion
## ℹ Input `STL` is `STL %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `BLK`.
## ℹ NAs introduced by coercion
## ℹ Input `BLK` is `BLK %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `TOV`.
## ℹ NAs introduced by coercion
## ℹ Input `TOV` is `TOV %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `PF`.
## ℹ NAs introduced by coercion
## ℹ Input `PF` is `PF %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `PTS`.
## ℹ NAs introduced by coercion
## ℹ Input `PTS` is `PTS %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## parsed http://www.basketball-reference.com/leagues/NBA_2020_totals.html
## Warning: All elements of `...` must be named.
## Did you want `dataTable = c(isSeasonCurrent, slugPlayerSeason, slugPlayerBREF, namePlayer, 
##     slugPosition, agePlayer, slugTeamBREF, countGames, countGamesStarted, 
##     minutes, fgm, fga, pctFG, fg3m, fg3a, pctFG3, fg2m, fg2a, 
##     pctFG2, pctEFG, ftm, fta, pctFT, orb, drb, trb, ast, stl, 
##     blk, tov, pf, pts, isHOFPlayer, slugTeamsBREF, countTeamsPlayerSeason)`?
## Advanced
## Warning: `cols` is now required when using unnest().
## Please use `cols = c(dataTable)`
## Warning: The `x` argument of `as_tibble.matrix()` must have unique column names if `.name_repair` is omitted as of tibble 2.0.0.
## Using compatibility `.name_repair`.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.
## 
## Attaching package: 'purrr'
## The following object is masked from 'package:plyr':
## 
##     compact
## Totals
## Warning: `cols` is now required when using unnest().
## Please use `cols = c(dataTable)`
## Warning: Unknown columns: `typeData`
## Joining, by = c("slugSeason", "yearSeason", "isSeasonCurrent", "slugPlayerSeason", "slugPlayerBREF", "namePlayer", "slugPosition", "agePlayer", "slugTeamBREF", "countGames", "isHOFPlayer", "slugTeamsBREF", "idPlayerNBA", "urlPlayerThumbnail", "urlPlayerHeadshot", "urlPlayerPhoto", "urlPlayerStats", "urlPlayerActionPhoto")
## # A tibble: 529 x 67
##    slugSeason namePlayer groupPosition yearSeason slugPosition isSeasonCurrent
##    <chr>      <chr>      <chr>              <dbl> <chr>        <lgl>          
##  1 2019-20    Steven Ad… C                   2020 C            FALSE          
##  2 2019-20    Bam Adeba… F                   2020 PF           FALSE          
##  3 2019-20    LaMarcus … C                   2020 C            FALSE          
##  4 2019-20    Kyle Alex… F                   2020 PF           FALSE          
##  5 2019-20    Nickeil A… G                   2020 SG           FALSE          
##  6 2019-20    Grayson A… G                   2020 SG           FALSE          
##  7 2019-20    Jarrett A… C                   2020 C            FALSE          
##  8 2019-20    Kadeem Al… G                   2020 SG           FALSE          
##  9 2019-20    Al-Farouq… F                   2020 PF           FALSE          
## 10 2019-20    Justin An… F                   2020 SF           FALSE          
## # … with 519 more rows, and 61 more variables: slugPlayerSeason <chr>,
## #   slugPlayerBREF <chr>, agePlayer <dbl>, slugTeamBREF <chr>,
## #   countGames <dbl>, isHOFPlayer <lgl>, slugTeamsBREF <chr>,
## #   idPlayerNBA <dbl>, urlPlayerThumbnail <chr>, urlPlayerHeadshot <chr>,
## #   urlPlayerPhoto <chr>, urlPlayerStats <chr>, urlPlayerActionPhoto <chr>,
## #   minutes <dbl>, ratioPER <dbl>, pctTrueShooting <dbl>, pct3PRate <dbl>,
## #   pctFTRate <dbl>, pctORB <dbl>, pctDRB <dbl>, pctTRB <dbl>, pctAST <dbl>,
## #   pctSTL <dbl>, pctBLK <dbl>, pctTOV <dbl>, pctUSG <dbl>, ratioOWS <dbl>,
## #   ratioDWS <dbl>, ratioWS <dbl>, ratioWSPer48 <dbl>, ratioOBPM <dbl>,
## #   ratioDBPM <dbl>, ratioBPM <dbl>, ratioVORP <dbl>,
## #   countTeamsPlayerSeason <dbl>, countGamesStarted <dbl>, pctFG <dbl>,
## #   pctFG3 <dbl>, pctFG2 <dbl>, pctEFG <dbl>, pctFT <dbl>, minutesTotals <dbl>,
## #   fgmTotals <dbl>, fgaTotals <dbl>, fg3mTotals <dbl>, fg3aTotals <dbl>,
## #   fg2mTotals <dbl>, fg2aTotals <dbl>, ftmTotals <dbl>, ftaTotals <dbl>,
## #   orbTotals <dbl>, drbTotals <dbl>, trbTotals <dbl>, astTotals <dbl>,
## #   stlTotals <dbl>, blkTotals <dbl>, tovTotals <dbl>, pfTotals <dbl>,
## #   ptsTotals <dbl>, countTeamsPlayerSeasonTotals <dbl>, urlPlayerBREF <chr>
bref_advanced <- dataBREFPlayerAdvanced
bref_totals <- dataBREFPlayerTotals
# Filter down to more than 500 total minutes and url shenanigans
adv_player_stats <- bref_advanced %>%
  filter(minutes >= 500) %>%
  mutate(bref_url = glue::glue("https://www.basketball-reference.com/players/{stringr::str_sub(idPlayerNBA, 1, 1)}/{idPlayerNBA}.html"),
         bref_link = glue::glue('<a href="{bref_url}">{namePlayer}</a>'))
# Collapse into frontcourt and backcourt
unique_positions <- unique(bref_advanced$slugPosition)
frontcourt <- c("PF", "SF", "C", "PF-SF", "C-PF", "SG-PF", "SF-PF")
backcourt <- c("PG", "SG", "PG-SG", "SG-PG", "SF-SG", "SG-SF")

bref_efg <- bref_totals %>%
  select(one_of(c("idPlayerNBA", "pctEFG")))

adv_player_stats <- adv_player_stats %>%
  left_join(bref_efg, by = "idPlayerNBA") %>%
  mutate( "position" = case_when(
    slugPosition %in% frontcourt ~ "frontcourt",
    slugPosition %in% backcourt ~ "backcourt",
    TRUE ~ "other"),
    "position" = as.factor(position)
  )
# Uses NBA Stats API to get offensive and defensive rating
nbastatR::teams_players_stats(seasons = 2020, types = c("player"), tables = "general", measures = "Advanced", assign_to_environment = TRUE)
## Acquiring all player PerGame general Advanced split tables for the 2019-20 season
## Warning: Unknown columns: `orderSort`, `idLeague`, `namePlayerLastFirst`,
## `dateGameLastPlayed`
## Warning: Unknown columns: `idTeam`
## Joining, by = "numberTable"
## Warning: All elements of `...` must be named.
## Did you want `dataTable = c(typeMeasure, isPlusMinus, isPaceAdjust, isRank, idPlayoffRound, 
##     idMonth, idTeamOpponent, idPeriod, countLastNGames, namePlayer, 
##     slugTeam, idPlayer, idTeam, gp, pctWins, pctAST, pctOREB, 
##     pctDREB, pctTREB, pctTOVTeam, pctTOVE, pctEFG, pctTS, pctUSG, 
##     pctUSGE, fgm, fga, fgmPerGame, fgaPerGame, pctFG, gpRank, 
##     pctWinsRank, minutesRank, pctASTRank, pctOREBRank, pctDREBRank, 
##     pctTREBRank, pctTOVTmRank, pctEFGRank, pctTSRank, pctUSGRank, 
##     fgmRank, fgaRank, fgmPerGameRank, fgaPerGameRank, pctFGRank, 
##     agePlayer, wins, losses, minutes, ortgE, ortg, removeOFF_RATING, 
##     drtgE, drtg, removeDEF_RATING, netrtgE, netrtg, removeNET_RATING, 
##     ratioASTtoTO, ratioAST, paceE, pace, pacePer40PACE_PER40, 
##     removePACE, ratioPIE, possessions, winsRank, lossesRank, 
##     rankORTGE, ortgRank, removeOFF_RATING_RANK, rankDRTGE, drtgRank, 
##     removeDEF_RATING_RANK, rankNTRGE, netrtgRank, removeNET_RATING_RANK, 
##     ratioASTtoTORank, ratioASTRank, rankPCTOVE, rankPCTUSGE, 
##     rankPACEE, paceRank, removePACE_RANK, pieRank)`?
## Warning: `cols` is now required when using unnest().
## Please use `cols = c(dataTable)`
## # A tibble: 1 x 7
##   nameTable typeResult modeSearch slugSeason typeSeason   yearSeason dataTable  
##   <chr>     <chr>      <chr>      <chr>      <chr>             <dbl> <list>     
## 1 general   player     PerGame    2019-20    Regular Sea…       2020 <tibble [5…
player_rtgs <- dataGeneralPlayers %>%
  select(one_of(c("idPlayer", "ortg", "drtg")))

adv_player_stats <- adv_player_stats %>%
  left_join(player_rtgs, by = c("idPlayerNBA" = "idPlayer"))
# Graph of PER for players with 500 plus minutes
adv_player_stats %>%
  ggplot(aes(x = ratioPER)) +
  geom_histogram(alpha = 0.7, fill = "#011627") +
  labs(title = "PER for players with 500+ minutes",
       subtitle = "NBA 2019-2020 season",
       caption = glue::glue("data via nbastatR")) + theme_bw()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# Graph of VORP
adv_player_stats %>%
  ggplot(aes(x = ratioVORP)) +
  geom_histogram(alpha = 0.7, fill = "#011627") +
  labs(title = "Value Over Replacement Player (VORP)",
       subtitle = "NBA 2019-2020 season, players with 500+ minutes",
       caption = glue::glue("data via nbastatR")) + theme_bw()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# Graph of win shares
adv_player_stats %>%
  ggplot(aes(x = ratioWS)) +
  geom_histogram(alpha = 0.7, fill = "#011627") +
  labs(title = "Win Shares for players with 500+ minutes",
       subtitle = "NBA 2019-2020 season",
       caption = glue::glue("data via nbastatR")) + theme_bw()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

adv_player_stats %>%
  ggplot(aes(x = ratioOBPM, y = ratioDBPM)) +
  geom_point() +
  geom_hline(yintercept = 0, alpha = 0.6, lty = "dashed") +
  geom_vline(xintercept = 0, alpha = 0.6, lty = "dashed") +
  labs(title = "Offensive vs. Defensive Box Plus-Minus",
       subtitle = glue::glue("NBA 2019-2020 season"),
       caption = glue::glue("data via nbastatR"),
       x = "OBPM",
       y = "DBPM") + theme_bw()

# Get top 10 players for some variable
get_top10 <- function(df, column) {
  require(rlang)
  column <- enquo(column)
  dplyr::top_n(df, n = 10, wt = !!column) %>%
    pull(namePlayer)
}
# get top 10 for desired variable (in this case ratioBPM)
top10_BPM <- top_n(adv_player_stats, n = 10, wt = ratioBPM) %>%
  pull(namePlayer)

adv_player_stats %>%
  ggplot(aes(x = ratioOBPM, y = ratioDBPM)) +
  geom_point(color = "#011627") +
  gghighlight::gghighlight(namePlayer %in% top10_BPM, label_key = namePlayer,
                           label_params = list(fill = ggplot2::alpha("white", 0.8),
                                               box.padding = 0,
                                               family = "Roboto Condensed"),
                           unhighlighted_colour = "#007190") +
  geom_hline(yintercept = 0, alpha = 0.6, lty = "dashed") +
  geom_vline(xintercept = 0, alpha = 0.6, lty = "dashed") +
  labs(title = "Offensive vs. Defensive Box Plus-Minus: Top 10 Box Plus/Minus",
       subtitle = glue::glue("NBA 2019-2020 Season"),
       caption = glue::glue("data via nbastatR"),
       x = "OBPM",
       y = "DBPM")
## Warning: The `unhighlighted_colour` argument of `gghighlight()` is deprecated as of gghighlight 0.2.0.
## Please use the `unhighlighted_params` argument instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.

adv_player_stats %>%
  select(namePlayer, slugPosition, ratioBPM, ratioOBPM, ratioDBPM, bref_url, urlPlayerHeadshot) %>%
  arrange(desc(ratioBPM)) %>%
  top_n(n = 10, wt = ratioBPM) %>%
  gt::gt(rowname_col = "namePlayer") %>%
  tab_header(
    title = md("**Top 10 Box Plus/Minus**")
  ) %>%
  cols_label(
    slugPosition = md("**Position**"),
    ratioBPM = md("**BPM**"),
    ratioOBPM = md("**OBPM**"),
    ratioDBPM = md("**DBPM**"),
    bref_url = md("**Link**"),
    urlPlayerHeadshot = md("")
  ) %>%
  text_transform(
    locations = cells_data(vars(bref_url)),
    fn = function(x) {
      sprintf("<a href=%s>profile</a>", x)
    }
  ) %>%
    text_transform(
    locations = cells_data(vars(urlPlayerHeadshot)),
    fn = function(x) {
      web_image(url = x) 
    }
  ) %>%
  tab_source_note(
    md("source: [basketball-reference.com](https://www.basketball-reference.com) via [nbastatR](http://asbcllc.com/nbastatR/index.html)")
  ) %>%
  tab_footnote(
    footnote = ("Players with 500+ minutes."),
    locations = cells_title("title")
    ) %>%
  tab_footnote(
    footnote = ("Box Plus/Minus: a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team."),
    locations = cells_column_labels(
      columns = vars(ratioBPM)
    )
  ) %>%
  tab_footnote(
    footnote = ("Offensive Box Plus/Minus."),
    locations = cells_column_labels(
      columns = vars(ratioOBPM)
    )
  ) %>%
  tab_footnote(
    footnote = ("Defensive Box Plus/Minus."),
    locations = cells_column_labels(
      columns = vars(ratioDBPM)
    )
  ) %>%
  tab_options(table.width = px(640))
## Warning: The `cells_data()` function is deprecated and will soon be removed
##  * Use the `cells_body()` function instead

## Warning: The `cells_data()` function is deprecated and will soon be removed
##  * Use the `cells_body()` function instead
Top 10 Box Plus/Minus1
Position BPM2 OBPM3 DBPM4 Link
Giannis Antetokounmpo PF 11.5 7.4 4.1 profile
James Harden SG 9.6 8.1 1.6 profile
Kawhi Leonard SF 8.9 6.5 2.4 profile
Luka Doncic PG 8.4 7.4 1.0 profile
LeBron James PG 8.4 6.6 1.8 profile
Anthony Davis PF 8.0 5.4 2.6 profile
Karl-Anthony Towns C 7.8 7.0 0.8 profile
Kyrie Irving PG 7.7 6.7 0.9 profile
Damian Lillard PG 7.5 8.3 -0.9 profile
Nikola Jokic C 7.4 5.5 2.0 profile
source: basketball-reference.com via nbastatR

1 Players with 500+ minutes.

2 Box Plus/Minus: a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team.

3 Offensive Box Plus/Minus.

4 Defensive Box Plus/Minus.

adv_player_stats %>%
  select(urlPlayerHeadshot, namePlayer, slugPosition, ratioBPM, ratioOBPM, ratioDBPM) %>%
  arrange(desc(ratioOBPM)) %>%
  top_n(n = 10, wt = ratioOBPM) %>%
  gt::gt() %>%
  tab_header(
    title = md("**Top 10 Offensive Box Plus/Minus**")
  ) %>%
  cols_label(
    namePlayer = md("**Player**"),
    urlPlayerHeadshot = md(""),
    slugPosition = md("**Position**"),
    ratioBPM = md("**BPM**"),
    ratioOBPM = md("**OBPM**"),
    ratioDBPM = md("**DBPM**")
  ) %>%
    text_transform(
    locations = cells_data(vars(urlPlayerHeadshot)),
    fn = function(x) {
      web_image(url = x) 
    }
  ) %>%
  tab_source_note(
    md("source: [basketball-reference.com](https://www.basketball-reference.com) via [nbastatR](http://asbcllc.com/nbastatR/index.html)")
  ) %>%
  tab_footnote(
    footnote = ("Players with 500+ minutes."),
    locations = cells_title("title")
  ) %>%
  tab_footnote(
    footnote = ("Box Plus/Minus; a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team."),
    locations = cells_column_labels(
      columns = vars(ratioBPM)
    )
  ) %>%
  tab_footnote(
    footnote = ("Offensive Box Plus/Minus."),
    locations = cells_column_labels(
      columns = vars(ratioOBPM)
    )
  ) %>%
  tab_footnote(
    footnote = ("Defensive Box Plus/Minus."),
    locations = cells_column_labels(
      columns = vars(ratioDBPM)
    )
  ) %>%
  tab_options(table.width = px(640))
## Warning: The `cells_data()` function is deprecated and will soon be removed
##  * Use the `cells_body()` function instead
Top 10 Offensive Box Plus/Minus1
Player Position BPM2 OBPM3 DBPM4
Damian Lillard PG 7.5 8.3 -0.9
James Harden SG 9.6 8.1 1.6
Giannis Antetokounmpo PF 11.5 7.4 4.1
Luka Doncic PG 8.4 7.4 1.0
Karl-Anthony Towns C 7.8 7.0 0.8
Kyrie Irving PG 7.7 6.7 0.9
LeBron James PG 8.4 6.6 1.8
Kawhi Leonard SF 8.9 6.5 2.4
Trae Young PG 3.9 6.2 -2.3
Nikola Jokic C 7.4 5.5 2.0
source: basketball-reference.com via nbastatR

1 Players with 500+ minutes.

2 Box Plus/Minus; a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team.

3 Offensive Box Plus/Minus.

4 Defensive Box Plus/Minus.

adv_player_stats %>%
  select(urlPlayerHeadshot, namePlayer, slugPosition, ratioBPM, ratioOBPM, ratioDBPM) %>%
  arrange(desc(ratioDBPM)) %>%
  top_n(n = 10, wt = ratioDBPM) %>%
  gt::gt() %>%
  tab_header(
    title = md("**Top 10 Defensive Box Plus/Minus**")
  ) %>%
  cols_label(
    namePlayer = md("**Player**"),
    urlPlayerHeadshot = md(""),
    slugPosition = md("**Position**"),
    ratioBPM = md("**BPM**"),
    ratioOBPM = md("**OBPM**"),
    ratioDBPM = md("**DBPM**")
  ) %>%
    text_transform(
    locations = cells_data(vars(urlPlayerHeadshot)),
    fn = function(x) {
      web_image(url = x) 
    }
  ) %>%
  tab_source_note(
    md("source: [basketball-reference.com](https://www.basketball-reference.com) via [nbastatR](http://asbcllc.com/nbastatR/index.html)")
  ) %>%
  tab_footnote(
    footnote = ("Players with 500+ minutes."),
    locations = cells_title("title")
  ) %>%
  tab_footnote(
    footnote = ("Box Plus/Minus; a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team."),
    locations = cells_column_labels(
      columns = vars(ratioBPM)
    )
  ) %>%
  tab_footnote(
    footnote = ("Offensive Box Plus/Minus."),
    locations = cells_column_labels(
      columns = vars(ratioOBPM)
    )
  ) %>%
  tab_footnote(
    footnote = ("Defensive Box Plus/Minus."),
    locations = cells_column_labels(
      columns = vars(ratioDBPM)
    )
  ) %>%
  tab_options(table.width = px(640))
## Warning: The `cells_data()` function is deprecated and will soon be removed
##  * Use the `cells_body()` function instead
Top 10 Defensive Box Plus/Minus1
Player Position BPM2 OBPM3 DBPM4
Giannis Antetokounmpo PF 11.5 7.4 4.1
Nerlens Noel C 3.1 -0.3 3.4
Kris Dunn PG -0.6 -3.7 3.1
Matisse Thybulle SG 0.3 -2.8 3.1
Jonathan Isaac SF 2.3 -0.5 2.9
Marc Gasol C 1.6 -1.2 2.8
Anthony Davis PF 8.0 5.4 2.6
Patrick Beverley PG 2.2 -0.3 2.5
Brook Lopez C 2.0 -0.4 2.5
Alex Caruso PG -0.2 -2.6 2.4
Donte DiVincenzo SG 1.3 -1.1 2.4
Kawhi Leonard SF 8.9 6.5 2.4
source: basketball-reference.com via nbastatR

1 Players with 500+ minutes.

2 Box Plus/Minus; a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team.

3 Offensive Box Plus/Minus.

4 Defensive Box Plus/Minus.

library(highcharter)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
#> Highcharts (www.highcharts.com) is a Highsoft software product which is
#> not free for commercial and Governmental use
hchart(adv_player_stats, "scatter", hcaes(x = "ratioOBPM", y = "ratioDBPM", group = "position", name = "namePlayer", OBPM = "ratioOBPM", DBPM = "ratioDBPM", position = "position")) %>%
  hc_tooltip(pointFormat = "<b>{point.name}</b><br />OBPM: {point.OBPM}<br />DBPM: {point.DBPM}") %>%
  hc_title(text = "Offensive vs. Defensive Box Plus/Minus") %>%
  hc_subtitle(text = "NBA 2019-2020 Season") %>%
  hc_credits(enabled = TRUE,
             text = "data via nbastatR",
             style = list(
               fontSize = "10px"
               )
             ) %>%
  hc_add_theme(hc_theme_538())
hchart(adv_player_stats, "scatter", hcaes(x = "ratioOWS", y = "ratioDWS", group = "position", name = "namePlayer", OWS = "ratioOWS", DWS = "ratioDWS", position = "position")) %>%
  hc_tooltip(pointFormat = "<b>{point.name}</b><br />OWS: {point.OWS}<br />DWS: {point.DWS}") %>%
  hc_title(text = "Offensive vs. Defensive Win Shares") %>%
  hc_subtitle(text = "NBA 2019-2020 Season") %>%
  hc_credits(enabled = TRUE,
             text = "data via nbastatR",
             style = list(
               fontSize = "10px"
               )
             ) %>%
  hc_add_theme(hc_theme_economist())
hchart(adv_player_stats, "scatter", 
       hcaes(x = "pctTrueShooting", y = "ratioPER",
             name = "namePlayer", TS = "pctTrueShooting", 
             PER = "ratioPER", position = "position")) %>%
  hc_tooltip(pointFormat = "<b>{point.name}</b><br />TS%: {point.TS}<br />PER: {point.PER}<br />Position: {point.position}") %>%
  hc_title(text = "True Shooting % vs Player Efficiency Rating") %>%
  hc_subtitle(text = "NBA 2019-2020 Season") %>%
  hc_credits(enabled = TRUE,
             text = "data via nbastatR",
             style = list(
               fontSize = "14px"
               )
             ) %>%
  hc_add_theme(hc_theme_chalk(
    plotOptions = list(
      scatter = list(
        marker = list(radius = 4,
                      fillOpacity = 0.3) # actually this does nothing
        )
      )
    )
  )
hc <- hchart(adv_player_stats, "scatter", hcaes(x = "ratioOWS", y = "ratioDWS", group = "position", name = "namePlayer", OWS = "ratioOWS", DWS = "ratioDWS", Position = "position")) %>%
  hc_tooltip(pointFormat = "<b>{point.name}</b><br />OWS: {point.OWS}<br />DWS: {point.DWS}") %>%
  hc_title(text = "Offensive vs. Defensive Win Shares") %>%
  hc_subtitle(text = "NBA 2019-2020 Season") %>%
  hc_credits(enabled = TRUE,
             text = "via nbastatR",
             href = "https://github.com/abresler/nbastatR",
             style = list(
               fontSize = "10px",
               color = "#4a4a4a"
               )
             ) 
hc2 <- hchart(adv_player_stats, "scatter", 
       hcaes(x = "ortg", y = "drtg", group = "position",
             name = "namePlayer", ortg = "ortg", 
             drtg = "drtg", position = "position")) %>%
  hc_tooltip(pointFormat = "<b>{point.name}</b><br />ORTG: {point.ortg}<br />DRTG: {point.drtg}<br />Position: {point.position}") %>%
  hc_title(text = "Offensive vs. Defensive Rating") %>%
  hc_subtitle(text = "NBA 2019-2020 Season") %>%
  hc_credits(enabled = TRUE,
             text = "data via nbastatR",
             style = list(
               fontSize = "14px"
               )
             )
hc
hc2
adv_player_stats %>%
  select(namePlayer, slugPosition, ratioBPM, ratioOBPM, ratioDBPM, bref_url, urlPlayerHeadshot) %>%
  arrange(desc(ratioBPM)) %>%
  top_n(n = 10, wt = ratioBPM) %>%
  gt::gt(rowname_col = "namePlayer") %>%
  tab_header(
    title = md("**Top 10 Box Plus/Minus**")
  ) %>%
  cols_label(
    slugPosition = md("**Position**"),
    ratioBPM = md("**BPM**"),
    ratioOBPM = md("**OBPM**"),
    ratioDBPM = md("**DBPM**"),
    bref_url = md("**Link**"),
    urlPlayerHeadshot = md("")
  ) %>%
  text_transform(
    locations = cells_data(vars(bref_url)),
    fn = function(x) {
      sprintf("<a href=%s>profile</a>", x)
    }
  ) %>%
    text_transform(
    locations = cells_data(vars(urlPlayerHeadshot)),
    fn = function(x) {
      web_image(url = x) 
    }
  ) %>%
  tab_source_note(
    md("source: [basketball-reference.com](https://www.basketball-reference.com) via [nbastatR](http://asbcllc.com/nbastatR/index.html)")
  ) %>%
  tab_footnote(
    footnote = ("Players with 500+ minutes."),
    locations = cells_title("title")
    ) %>%
  tab_footnote(
    footnote = ("Box Plus/Minus: a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team."),
    locations = cells_column_labels(
      columns = vars(ratioBPM)
    )
  ) %>%
  tab_footnote(
    footnote = ("Offensive Box Plus/Minus."),
    locations = cells_column_labels(
      columns = vars(ratioOBPM)
    )
  ) %>%
  tab_footnote(
    footnote = ("Defensive Box Plus/Minus."),
    locations = cells_column_labels(
      columns = vars(ratioDBPM)
    )
  ) %>%
  tab_options(table.width = px(640))
## Warning: The `cells_data()` function is deprecated and will soon be removed
##  * Use the `cells_body()` function instead

## Warning: The `cells_data()` function is deprecated and will soon be removed
##  * Use the `cells_body()` function instead
Top 10 Box Plus/Minus1
Position BPM2 OBPM3 DBPM4 Link
Giannis Antetokounmpo PF 11.5 7.4 4.1 profile
James Harden SG 9.6 8.1 1.6 profile
Kawhi Leonard SF 8.9 6.5 2.4 profile
Luka Doncic PG 8.4 7.4 1.0 profile
LeBron James PG 8.4 6.6 1.8 profile
Anthony Davis PF 8.0 5.4 2.6 profile
Karl-Anthony Towns C 7.8 7.0 0.8 profile
Kyrie Irving PG 7.7 6.7 0.9 profile
Damian Lillard PG 7.5 8.3 -0.9 profile
Nikola Jokic C 7.4 5.5 2.0 profile
source: basketball-reference.com via nbastatR

1 Players with 500+ minutes.

2 Box Plus/Minus: a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team.

3 Offensive Box Plus/Minus.

4 Defensive Box Plus/Minus.